package com.simplegui.swing;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.util.HashSet;
import java.util.Set;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import com.simplegui.api.Canvas;
import com.simplegui.api.DynamicFrame;
import com.simplegui.api.Frame;
import com.simplegui.api.handlers.ButtonHandler;
import com.simplegui.api.handlers.DrawHandler;
import com.simplegui.api.handlers.KeyDownHandler;
import com.simplegui.api.handlers.KeyUpHandler;
import com.simplegui.api.util.FrameRatePerSecondCounter;
import com.simplegui.api.util.Key;

@SuppressWarnings("serial")
public class FrameSwingImpl extends JFrame implements Frame{
	
	private BufferedImage image;
	private JPanel controlPanel;
	private JPanel panel;
	private JLabel lblFrameRate;
	private DynamicFrame frame;
	private DrawHandler drawHandler;
	private KeyDownHandler keyDownHandler;
	private KeyUpHandler keyUpHandler;
	private FrameRatePerSecondCounter frameRateCounter;
	
	public FrameSwingImpl(String title, Dimension dimension) {
		super(title);
		initComponents(dimension);
		initLayout(dimension);
		initListeners();
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	private void initComponents(Dimension dimension) {
		image = new BufferedImage(dimension.width, dimension.height, BufferedImage.TYPE_INT_RGB);
		
		controlPanel = new JPanel(new FlowLayout());
		
		panel = new JPanel(){
			@Override
			public void paint(Graphics g) {
				g.drawImage(image, 0, 0, null);
			}
			
		};
		
		final Canvas canvas = new CanvasSwingImpl(image);
		frame = new DynamicFrame() {
			@Override
			protected Canvas getCanvas() {
				return canvas;
			}

			@Override
			protected void repaint() {
				panel.repaint();
			}

			@Override
			protected DrawHandler getDrawHandler() {
				return drawHandler;
			}
			
			@Override
			public KeyDownHandler getKeyDownHandler() {
				return keyDownHandler;
			}
			
			@Override
			public KeyUpHandler getKeyUpHandler() {
				return keyUpHandler;
			}
		};
		
		lblFrameRate = new JLabel();
		
		frameRateCounter = new FrameRatePerSecondCounter(){
			@Override
			protected void framesPerSecondChanged() {
				lblFrameRate.setText("Frame rate:" + getFramesPerSecond());
			}
		};
		frame.getFrameRateThread().addFrameHateListener(frameRateCounter);
		
	}
	
	private void initLayout(Dimension dimension) {
		setBounds(0, 0, dimension.width+150, dimension.height+70);
		setLocationRelativeTo(null);
		
		JPanel centralPanel = new JPanel(new FlowLayout());
		panel.setPreferredSize(dimension);
		centralPanel.add(panel);
		
		setLayout(new BorderLayout());
		add(controlPanel, BorderLayout.WEST);
		add(lblFrameRate, BorderLayout.SOUTH);
		add(centralPanel, BorderLayout.CENTER);
		
	}
	
	private void initListeners() {
		final Set<Key> pressedKeys = new HashSet<Key>();
		
		addKeyListener(new KeyListener() {
			
			@Override
			public void keyTyped(KeyEvent e) {}
			
			@Override
			public void keyReleased(KeyEvent e) {
				Key key = Key.getFromKeyEvent(e);
				pressedKeys.remove(key);
				if(keyUpHandler != null){
					keyUpHandler.onKeyUp(key);
				}
			}
			
			@Override
			public void keyPressed(KeyEvent e) {
				Key key = Key.getFromKeyEvent(e);
				if(pressedKeys.add(key) && keyDownHandler != null){
					keyDownHandler.onKeyDown(key);
				}
			}
		});
	}

	@Override
	public void start(){
		frame.start();
		setVisible(true);
	}
	
	@Override
	public void setDrawHandler(DrawHandler drawHandler) {
		this.drawHandler = drawHandler;
	}
	
	@Override
	public void setKeyUpHandler(KeyUpHandler keyUpHandler) {
		this.keyUpHandler = keyUpHandler;
	}
	
	@Override
	public void setKeyDownHandler(KeyDownHandler keyDownHandler) {
		this.keyDownHandler = keyDownHandler;
	}

	@Override
	public void addButton(String label, final ButtonHandler buttonHandler) {
		JButton btn = new JButton(label);
		btn.setFocusable(false);
		btn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				buttonHandler.onButtonPress();
			}
		});
		controlPanel.add(btn);
	}


}
